package com.sp.scmdb.serviceImpl;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.sp.scmdb.bean.RoleBean;
import com.sp.scmdb.bean.CheckBoxEntityBean;
import com.sp.scmdb.bean.MenuEntityBean;
import com.sp.scmdb.bean.UserBean;
import com.sp.scmdb.common.CommonParamter;
import com.sp.scmdb.entity.Department;
import com.sp.scmdb.entity.Menu;
import com.sp.scmdb.dao.DepartmentDao;
import com.sp.scmdb.dao.MenuDao;
import com.sp.scmdb.dao.RoleDao;
import com.sp.scmdb.entity.Role;
import com.sp.scmdb.service.LogService;
import com.sp.scmdb.service.RoleService;

@Service("roleService")
public class RoleServiceImpl implements RoleService {

	/** 角色管理Dao接口 */
	private RoleDao roleDao;
	
	/** 菜单Dao */
	private MenuDao menuDao;
	
	/** 角色Dao */
	private DepartmentDao departmentDao;
	
	private LogService logs;

	public void setLogs(LogService logs) {
		this.logs = logs;
	}
	
	public void setDepartmentDao(DepartmentDao departmentDao) {
		this.departmentDao = departmentDao;
	}

	public void setMenuDao(MenuDao menuDao) {
		this.menuDao = menuDao;
	}

	public void setRoleDao(RoleDao roleDao) {
		this.roleDao = roleDao;
	}

	/**
	 * 查询所有的角色列表，并转换成页面输出的格式
	 */
	@Transactional(readOnly = true)
	public List<RoleBean> findAll() {
		
		// 角色列表
		List<Role> list = roleDao.queryAll();
		Role role = null;
				
		// 查询页面查询结果列表
		List<RoleBean> roleList = new ArrayList<RoleBean>();
		RoleBean searchRoleBean = null;
	try{
		for (int i = 0; i < list.size(); i++) {
			// 取出每一个角色实体，并将其转换成页面输出的格式
			role = list.get(i);
			
			// 查询页面查询结果Bean
			searchRoleBean = new RoleBean();
			searchRoleBean.setId(String.valueOf(role.getId()));
			searchRoleBean.setName(role.getName());
			searchRoleBean.setMenu(this.getMenuByMenuID(role.getMenu()));
			searchRoleBean.setDepartment(this.getDepartmentByDepartmentID(role.getDepartment()));
			searchRoleBean.setOperation(role.getOperation());
			roleList.add(searchRoleBean);
		}		
	}catch (Exception e) {
		// TODO: handle exception
		e.printStackTrace();
	}
		return roleList;
	}	

	/**
	 * 查询菜单列表
	 */
	@Transactional(readOnly = true)
	public List<MenuEntityBean> queryMenu(UserBean user) {
		// 数据库查询出来的所有菜单列表
		List<Menu> listMenu = menuDao.queryHql("from Menu order by id asc");
		listMenu = this.menuFilter(user, listMenu);
		Menu menu = null;
		
		// 页面显示的菜单列表
		List<MenuEntityBean> liseMenuEntityBean = new ArrayList<MenuEntityBean>();
		MenuEntityBean menuEntityBean = null;
		CheckBoxEntityBean checkBox = null;
		// 首先构造出一级菜单
		for (int i = 0; i < listMenu.size(); i++) {
			menu = listMenu.get(i);
			// 如果菜单的父菜单为空（pCd=null），则说明该菜单就是一级菜单
			if (StringUtils.isEmpty(menu.getPCd())) {
				menuEntityBean = new MenuEntityBean();
				// 一级菜单
				checkBox = new CheckBoxEntityBean();
			    // 菜单id
				checkBox.setKey(String.valueOf(menu.getId()));
				// 菜单名称
				checkBox.setName(menu.getCdesc());
				menuEntityBean.setCheckBox(checkBox);
				// 构造出一个空的子菜单列表
				menuEntityBean.setCheckBoxList(new ArrayList<CheckBoxEntityBean>());
				// 将该一级单菜单加入菜单列表
				liseMenuEntityBean.add(menuEntityBean);
			}
		}
		// 循环一级菜单列表，构造出每个一级菜单下面的子菜单
		String id = "";
		for(int i = 0; i < liseMenuEntityBean.size(); i++) {
			menuEntityBean = liseMenuEntityBean.get(i);
			for(int j = 0; j < listMenu.size(); j++) {
				menu = listMenu.get(j);
				// 首先取得该一级菜单的menu.id
				if (menuEntityBean.getCheckBox().getKey().equals(String.valueOf(menu.getId()))) {
					id = String.valueOf(menu.getId());
				}
				// 如果原始菜单的父菜单ID等于一级菜单ID，则将该菜单至于一级菜单下面
				if (menuEntityBean.getCheckBox().getKey().equals(menu.getPCd())) {
					// 二级菜单
					checkBox = new CheckBoxEntityBean();
				    // 菜单id
					checkBox.setKey(String.valueOf(menu.getId()));
					// 菜单名称
					checkBox.setName(menu.getCdesc());
					// 将该二级菜单加入一级菜单
					menuEntityBean.getCheckBoxList().add(checkBox);
					// 重新修改最终菜单列表中的一级菜单信息
					liseMenuEntityBean.set(i, menuEntityBean);
				}
			}
			// 将该一级菜单的key由之前的menu.idMenu变为menu.id
			liseMenuEntityBean.get(i).getCheckBox().setKey(id);
		}
		return liseMenuEntityBean;
	}
	
	/**
	 * 查询角色列表
	 */
	@Transactional(readOnly = true)
	public List<CheckBoxEntityBean> queryDepartment(UserBean user){
		List<CheckBoxEntityBean> departmentList = new ArrayList<CheckBoxEntityBean>();
		CheckBoxEntityBean bean = null;
		
		List<Department> list = departmentDao.queryAll();
		// 过滤掉当前用户不拥有权限的角色
		list = this.departmentFilter(user, list);
		
		for (int i = 0; i < list.size(); i++) {
			bean = new CheckBoxEntityBean();
			bean.setChecked(0);
			bean.setKey(String.valueOf(list.get(i).getId()));
			bean.setName(list.get(i).getDeptName());
			
			departmentList.add(bean);
		}
		return departmentList;
	}
	
	/**
	 * 新建角色
	 */
	@Transactional
	public String newRole(RoleBean bean, UserBean user) {
		String request = "3";
		
		// 构造实体对象
		// 根据角色名称验证该名称角色是否已经存在
		StringBuffer Hql = new StringBuffer("from Role where 1=1 ");
		if (StringUtils.isNotEmpty(bean.getName())) {
			Hql.append(" and name='" + bean.getName() + "'");
			List<Role> listRole = roleDao.queryHql(Hql.toString());	
			if (CollectionUtils.isEmpty(listRole)) {
				// 如果该名称的角色不存在
				Role role = new Role();
				role.setName(bean.getName().trim());
				String menu = bean.getCheckRight();
				if (StringUtils.isNotEmpty(menu)) {
					menu = menu.substring(0, menu.length() - 1);
				}
				role.setMenu(menu);
				role.setDepartment(bean.getDepartment());
				role.setOperation(bean.getOperation());
				role.setLevel("1");
				
				// 持久化实体对象
				roleDao.save(role);
				logs.addLog(user, "添加 角色：\""+bean.getName()+"\"成功！");
				
				request = CommonParamter.CHECK_SUCCESS;
			} else {
				request = CommonParamter.CHECK_REPEAT;
			}
		}
		
		return request;
	}
	
	/**
	 * 根据角色ID取得角色
	 */
	@Transactional(readOnly = true)
	public RoleBean findRoleById(Integer id, UserBean user) {
		RoleBean roleBean = null;
		Role role = null;
		String Hql = "from Role where id='" + id + "'";
		// 取得角色信息
		List<Role> listRole = roleDao.queryHql(Hql);
		// 所有的菜单信息
		List<MenuEntityBean> liseMenuEntityBean = null;
	
		if (CollectionUtils.isNotEmpty(listRole)) {
			role = listRole.get(0);
			
			// 设置RoleBean属性
			roleBean = new RoleBean();
			roleBean.setName(role.getName());
			roleBean.setId(String.valueOf(role.getId()));
			roleBean.setOperation(role.getOperation());
			String department = role.getDepartment();
			if (null == department) {
				department = "";
			}
			roleBean.setDepartment(department);
			String menu = role.getMenu();
			if (null == menu) {
				menu = "";
			}
			roleBean.setMenu(menu);
			
			// 获取该角色所对应的菜单权限，首先取出所有的菜单列表
			liseMenuEntityBean = this.queryMenu(user);
			
			// 循环菜单列表，将该角色拥有权限的菜单选中
			MenuEntityBean menuEntityBean = null;
			for (int i = 0; i < liseMenuEntityBean.size(); i++) {
				menuEntityBean = liseMenuEntityBean.get(i);
				if (roleBean.getMenu().indexOf(menuEntityBean.getCheckBox().getKey()) >= 0) {
					// 如果该一级菜单存在于mapRoleMenu中，则将该菜单选中（checked=1）
					liseMenuEntityBean.get(i).getCheckBox().setChecked(1);
				}
				// 循环该一级菜单下面的二级菜单
				for (int j = 0; j < menuEntityBean.getCheckBoxList().size(); j++) {
					if (roleBean.getMenu().indexOf((menuEntityBean.getCheckBoxList().get(j).getKey())) >= 0) {
						// 如果该二级菜单存在于mapRoleMenu中，则将该菜单选中（checked=1）
						liseMenuEntityBean.get(i).getCheckBoxList().get(j).setChecked(1);
					}
				}
			}
			roleBean.setLiseMenuEntityBean(liseMenuEntityBean);
			
			// 获取所有角色列表
			List<CheckBoxEntityBean> listDepartment = this.queryDepartment(user);
			roleBean.setDepartmentList(listDepartment);
			// 获取该角色所对应的角色列表
			
			// 循环所有角色列表，该角色拥有权限的角色，设置其checked=1
			for (int i = 0, size = listDepartment.size(); i < size; i++) {
				if (roleBean.getDepartment().indexOf(listDepartment.get(i).getKey()) >= 0) {
					// 如果该角色所对应的角色角色关系表存在该角色ID，则设置该角色Bean的checked=1
					listDepartment.get(i).setChecked(1);
				} else {
					listDepartment.get(i).setChecked(0);
				}
			}
			roleBean.setDepartmentList(listDepartment);
		}
		roleBean.setCheckRight(roleBean.getMenu() + ",");
		
		return roleBean;
	} 
	
	/**
	 * 修改角色
	 */
	@Transactional
	public String editRole(RoleBean bean, UserBean user) {
		String result = "";
		// 检查该角色是否存在
		Role role = roleDao.getById(Integer.parseInt(bean.getId()));
		if (role != null) {
			// 检查角色名称是否重复
			if (StringUtils.isNotEmpty(bean.getName())) {
				StringBuffer Hql = new StringBuffer();
				Hql.append("from Role where id != " + bean.getId()
						+ " and name = '" + bean.getName() + "'");
				if (CollectionUtils.isEmpty(roleDao.queryHql(Hql.toString()))) {
					// 如果名称没有重复的
					role.setName(bean.getName().trim());
					String menu = bean.getCheckRight();
					if (StringUtils.isNotEmpty(menu)) {
						if(menu.substring(0,1).equals(",")){
							menu = menu.substring(1, menu.length() - 1);
						}else{
							menu = menu.substring(0, menu.length() - 1);
						}
					}
					role.setMenu(menu);
					role.setDepartment(bean.getDepartment());
					role.setOperation(bean.getOperation());
					// 保存该角色
					roleDao.update(role);
					logs.addLog(user, "修改 角色：\""+bean.getName()+"\"成功！");
					result = CommonParamter.CHECK_SUCCESS;
				} else {
					result = CommonParamter.CHECK_REPEAT;
				}
			}
		}
		return result;
	}
	
	/**
	 * 根据菜单ID获取菜单名称
	 * @param menuID 菜单ID：例如:100101 或者:100101,100102
	 * @return 菜单名称
	 */
	@Transactional(readOnly = true)
	private String getMenuByMenuID(String menuID) {
		if (null == menuID || "".equals(menuID)) {
			return "";
		}
		String[] menuIDs = menuID.split(",");
		StringBuffer menu = new StringBuffer();
		for (int i = 0; i < menuIDs.length; i++) {
			menu.append(menuDao.getById(Integer.parseInt(menuIDs[i])).getCdesc());
			menu.append(",");
		}
		
		// 如果menu不为空，则去掉它最后的一个“,”后返回，否则返回空串
		return menu.length() > 0 ? menu.substring(0, menu.length() - 1 ).toString() : "";
	}
	
	/**
	 * 删除角色
	 */
	@Transactional
	public String delRole(String ids, UserBean user) {
		String result = "1";
		// 检查该角色是否存在
		StringBuffer Hql = null; 
		String[] idArray = ids.split(",");
		for (int i = 0; i < idArray.length; i++) {
			Hql = new StringBuffer("from Role where id ='" + idArray[i] + "'");
			List<Role> listRole = roleDao.queryHql(Hql.toString());
			if (CollectionUtils.isNotEmpty(listRole)) {
				// 如果该角色存在
				Role role = listRole.get(0);
				
				// 如果该角色是非超级管理员，才能删除
				if (!"0".equals(role.getLevel())) {	
					logs.addLog(user, "删除 角色：\""+role.getName()+"\"成功！");
					// 删除该角色（OBJ_ROLE）
					roleDao.delete(role);
					result = CommonParamter.CHECK_SUCCESS;
				} else {					
					result = "10";
				}
			} else {
				result = CommonParamter.CHECK_REPEAT;
			}
		}
		
		return result;
	}
	
	/**
	 * 根据部门ID获取部门名称
	 * @param departmentID 部门ID：例如:100101 或者:100101,100102
	 * @return 部门名称
	 */
	@Transactional(readOnly = true)
	private String getDepartmentByDepartmentID(String departmentID) {
		if (departmentID == null || "".equals(departmentID)) {
			return "";
		}
		String[] departmentIDs = departmentID.split(",");
		StringBuffer department = new StringBuffer();
		Department entity = null;
		for (int i = 0; i < departmentIDs.length; i++) {
			entity = departmentDao.getById(Integer.parseInt(departmentIDs[i].trim()));
			if (entity != null) {
				department.append(entity.getDeptName());
				department.append(",");
			}
		}
		
		// 如果department不为空，则去掉它最后的一个“,”后返回，否则返回空串
		return department.length() > 0 ? department.substring(0, department.length() - 1 ).toString() : "";
	}
	
	/**
	 * 根据当前用户的权限，过滤掉该用户不拥有权限的菜单
	 * @param user 当前用户信息
	 * @param list 需要过滤的菜单列表
	 * @return 过滤掉不拥有权限的菜单之后的菜单列表
	 */
	private List<Menu> menuFilter(UserBean user, List<Menu> list){
		// 如果当前用户是超级管理员角色(level=0)，则不作任何过滤
		if ("0".equals(user.getRole().getLevel())) {
			return list;
		}
		// 获取当前用户的菜单权限 注：注释代码为过滤读取。
		String menuUser = user.getRole().getMenu();
		List<Menu> listResult = new ArrayList<Menu>();
		Menu menu = null;
		for (int i = 0; i < list.size(); i++) {
			//if (menuUser.indexOf(list.get(i).getId().toString()) >= 0) { //注释过滤
				menu = list.get(i);
				listResult.add(menu);
			//}
		}
		return listResult;
	}
	
	/**
	 * 根据当前用户的权限，过滤掉该用户不拥有权限的部门
	 * @param user 当前用户信息
	 * @param list 需要过滤的部门列表
	 * @return 过滤掉不拥有权限的角色之后的部门列表
	 */
	private List<Department> departmentFilter(UserBean user, List<Department> list){
		// 如果当前用户是超级管理员角色(level=0)，则不作任何过滤
		if ("0".equals(user.getRole().getLevel())) {
			return list;
		}
		// 获取当前用户的菜单权限
		String departmentUser = user.getRole().getDepartment();
		List<Department> listResult = new ArrayList<Department>();
		Department department = null;
		for (int i = 0; i < list.size(); i++) {
			if (departmentUser.indexOf(list.get(i).getId().toString()) >= 0) {
				department = list.get(i);
				listResult.add(department);
			}
		}
		return listResult;
	}
	
	public Role getById(Integer id) {
		return roleDao.getById(id);
	}
}
